#ifndef _COORDINATOR_H_
#define _COORDINATOR_H_

#include <memory>
#include <vector>
#include <mutex>
#include "modules/module.h"
#include "modules/WebRadio.h"
#include "modules/StandbyControl.h"
#include "modules/WifiControl.h"

class Coordinator;
#include "hw/Button.h"

#include <deque>

/** 
Centralize events from buttons and forward it to active module if necessary
start/stop/pause modules. Set active module
*/
class Coordinator : public module{
public :
    /** @credential_path path to XML file containig wif credentials (ESSID/password) */
    Coordinator(std::shared_ptr<Samsung_20T202DA2JA> screen,
        std::shared_ptr<std::vector<std::shared_ptr<Button> > > button_vector,
        std::string credential_path)
            : module(screen),
            m_button_list(button_vector),
            m_wifi_credential_list_path(credential_path)
        {
            init();
        }
    
protected:
    std::shared_ptr<module> m_active_module;
    
    std::shared_ptr<WebRadio> m_web_radio;
    std::shared_ptr<StandbyControl> m_standby_ctrl;
    std::shared_ptr<WifiControl> m_wifi_ctrl;
    
    int init();
    virtual int threadHandler();
    
    /** process events from buttons (mostly) */
    int handleEvent(std::shared_ptr<ButtonEvent> e);
    int change_mode();
    
    /** process messages */
    int handleMessage(std::shared_ptr<Message> m);
    
    /** current button state/value according to present processed event */
    int m_value_switch_net_mode;
    int m_value_switch_mode;
    int m_value_aux_in_1;
    int m_value_aux_in_2;
    int m_value_onoff;
    std::mutex m_value_mutex;
    
    /** input (bouttons) changed, active mode should be updated
    allows to effectively change mode after a delay */
    bool m_change_mode_flag;
    /** time point of the last time m_change_mode_flag has been set to true*/
    std::chrono::high_resolution_clock::time_point m_change_mode_tp;
    /** list of all buttons, useful for pause/resume (saves cycle when standby) */
    std::shared_ptr<std::vector<std::shared_ptr<Button> > > m_button_list;
    
    /** path to XML file containig wif credentials (ESSID/password) */
    std::string m_wifi_credential_list_path;
    friend WifiControl;
    
private:
    enum State{
        STATE_NULL,
        STATE_STANDBY,
        STATE_AUX_1,
        STATE_AUX_2,
        STATE_REMOTE,
        STATE_WEB_RADIO
    };
    /** active state*/
    State m_current_state;
    /** active newtork state */
    NetState m_current_net_state;
    
    /** saves cycle/energy) */
    void pause_buttons();
    void resume_buttons();
    
    /** turn on/off power if not already turned on/off, delay after set */
    void amp_power_on();
    void amp_power_off();
};

#endif
